package com.fary.web.servlet.handler;

import com.fary.beans.factory.BeanFactoryUtils;
import com.fary.context.ApplicationContext;
import com.fary.core.SpringException;
import com.fary.util.ObjectUtils;

public abstract class AbstractDetectingUrlHandlerMapping extends AbstractUrlHandlerMapping {

	private boolean detectHandlersInAncestorContexts = false;

	/**
	 * 设置是否检测父容器
	 */
	public void setDetectHandlersInAncestorContexts(boolean detectHandlersInAncestorContexts) {
		this.detectHandlersInAncestorContexts = detectHandlersInAncestorContexts;
	}

	@Override
	public void initApplicationContext() throws SpringException {
		super.initApplicationContext();
		detectHandlers();
	}

	/**
	 * 检测bean容器中，所有beanName的以"/"开头，然后注册处理器
	 */
	protected void detectHandlers() throws SpringException {
		ApplicationContext applicationContext = obtainApplicationContext();
		String[] beanNames = (this.detectHandlersInAncestorContexts ?
				BeanFactoryUtils.beanNamesForTypeIncludingAncestors(applicationContext, Object.class) :
				applicationContext.getBeanNamesForType(Object.class));

		// Take any bean name that we can determine URLs for.
		for (String beanName : beanNames) {
			String[] urls = determineUrlsForHandler(beanName);
			if (!ObjectUtils.isEmpty(urls)) {
				registerHandler(urls, beanName);
			}
		}

		if ((logger.isDebugEnabled() && !getHandlerMap().isEmpty()) || logger.isTraceEnabled()) {
			logger.debug("Detected " + getHandlerMap().size() + " mappings in " + formatMappingName());
		}
	}


	/**
	 * 确定给定处理程序 bean 的 URL
	 */
	protected abstract String[] determineUrlsForHandler(String beanName);

}